﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Common.Utilities;
using Common.Utilities.Dispatcher;

namespace Workflows.Components.Entities.Relations.DirectAssociations
{
    public partial class EntityLinkageEditor : Form, IComponentEditor 
    {
        private object _ActivityNode;
        private EntityLinkageComponent _LinkageComponent;


        public EntityLinkageEditor()
        {
            InitializeComponent();
        }

        private void EntityLinkageEditor_Load(object sender, EventArgs e)
        {
            this.cbo_RefTypes.Items.Clear();
            for (int i = 0; i <= 2; i++)
            {
                EntityReferenceType refType = (EntityReferenceType)i;
                this.cbo_RefTypes.Items.Add(refType.ToString());
            }

            this.cbo_SrcDbProvider.Items.Clear();
            this.cbo_RefDbProvider.Items.Clear();
            for(int i=0;i<=1;i++)
            {
                DataProviderType dbProvider = (DataProviderType)i;
                this.cbo_SrcDbProvider.Items.Add(dbProvider.ToString());
                this.cbo_RefDbProvider.Items.Add(dbProvider.ToString());
            }
        }

        #region IComponentEditor Members

        public event UpdateComponentSettings UpdateComponentSettingEvent;

        public object OwnerActivityNode
        {
            get { return _ActivityNode; }
            set { _ActivityNode = value; }
        }

        public Type WorkflowComponentType
        {
            get { return typeof (EntityLinkageComponent); }
        }

        public void LoadSettings(GlobalVariable[] globalVars, WorkflowComponentBase[] fromComponents,
                                 object activityNode, WorkflowComponentBase wfComponent)
        {
            this._ActivityNode = activityNode;
            this._LinkageComponent = (EntityLinkageComponent) wfComponent;

            this.cbo_SrcDbProvider.SelectedIndex = (int) this._LinkageComponent.ParentDbProvider;
            this.txt_SrcConnStr.Text = this._LinkageComponent.ParentConnStr;
            this.rt_SrcSql.Text = this._LinkageComponent.ParentSql;
            this.cbo_SrcKey.Items.Clear();
            
            if(!string.IsNullOrEmpty(this.txt_SrcConnStr.Text) && !string.IsNullOrEmpty(this.rt_SrcSql.Text))
            {
                TableColumn[] srcCols =
                    DbUtil.GetTableColumns(
                        this._LinkageComponent.ParentDbProvider, this.txt_SrcConnStr.Text, this.rt_SrcSql.Text);
                if(srcCols !=null && srcCols.Length>0)
                {
                    foreach(TableColumn col in srcCols)
                    {
                        this.cbo_SrcKey.Items.Add(col.ColumnName);
                        
                    }
                }
            }
            if(this.cbo_SrcKey.Items.Count>0 && !string.IsNullOrEmpty(this._LinkageComponent.ParentKeyFieldName))
            {
                for(int i=0;i<this.cbo_SrcKey.Items.Count;i++)
                {
                    if(this.cbo_SrcKey.Items[i].ToString()==this._LinkageComponent.ParentKeyFieldName)
                    {
                        this.cbo_SrcKey.SelectedIndex = i;
                        break;
                    }
                }
            }

            this.cbo_RefDbProvider.SelectedIndex = (int)this._LinkageComponent.ChildDbProvider;
            this.txt_RefConnStr.Text = this._LinkageComponent.ChildConnStr;
            this.rt_RefSql.Text = this._LinkageComponent.ChildSql;
            this.cbo_RefPK.Items.Clear();
            this.cbo_RefFK.Items.Clear();
            
            if(!string.IsNullOrEmpty(this.txt_RefConnStr.Text) && !string.IsNullOrEmpty(this.rt_RefSql.Text))
            {
                string sql = this.rt_RefSql.Text;
                if (sql.IndexOf("{0}") >= 0)
                {
                    sql = sql.Replace("{0}", "1");
                }

                TableColumn[] refCols =
                    DbUtil.GetTableColumns(
                        this._LinkageComponent.ChildDbProvider,
                        this.txt_RefConnStr.Text, sql);
                if(refCols !=null && refCols.Length>0)
                {
                    foreach(TableColumn col in refCols)
                    {
                        this.cbo_RefPK.Items.Add(col.ColumnName);
                        this.cbo_RefFK.Items.Add(col.ColumnName);
                    }
                }
            }
            if(this.cbo_RefFK.Items.Count>0 && 
                !string.IsNullOrEmpty(this._LinkageComponent.ChildFKFieldName))
            {
                for(int i=0;i<this.cbo_RefFK.Items.Count;i++)
                {
                    if (this.cbo_RefFK.Items[i].ToString() == this._LinkageComponent.ChildFKFieldName)
                    {
                        this.cbo_RefFK.SelectedIndex = i;
                        break;
                    }
                }
            }
            if(this.cbo_RefPK.Items.Count>0 && 
                !string.IsNullOrEmpty(this._LinkageComponent.ChildPKFieldName))
            {
                for (int i = 0; i < this.cbo_RefPK.Items.Count; i++)
                {
                    if(this.cbo_RefPK.Items[i].ToString()==this._LinkageComponent.ChildPKFieldName)
                    {
                        this.cbo_RefPK.SelectedIndex = i;
                        break;
                    }
                }
            }
            

            this.num_HopFactor.Value = (decimal)this._LinkageComponent.HopFactor;
            this.num_SimilarityThreshold.Value = (decimal)this._LinkageComponent.LinkageSimilarityThreshold;
            this.cbo_RefTypes.SelectedIndex = (int)this._LinkageComponent.ReferenceType;

            this.cbo_TgtDbProvider.SelectedIndex = (int)this._LinkageComponent.TgtDbProvider;
            this.txt_TgtConnStr.Text = this._LinkageComponent.TgtConnStr;
            this.cbo_TgtTable.Items.Clear();
            if(!string.IsNullOrEmpty(this._LinkageComponent.TgtConnStr))
            {
                string[] tblNames =
                    DbUtil.GetTableNames(this._LinkageComponent.TgtDbProvider, string.Empty,
                                         this._LinkageComponent.TgtConnStr);
                if(tblNames !=null && tblNames.Length>0)
                {
                    foreach(string tblName in tblNames)
                    {
                        this.cbo_TgtTable.Items.Add(tblName);
                    }
                }

                if(!string.IsNullOrEmpty(this._LinkageComponent.TgtTable))
                {
                    for(int i=0;i<this.cbo_TgtTable.Items.Count;i++)
                    {
                        if(this.cbo_TgtTable.Items[i].ToString()==this._LinkageComponent.TgtTable)
                        {
                            this.cbo_TgtTable.SelectedIndex = i;
                            break;
                        }
                    }
                }

                if(this.cbo_TgtSrcKey.Items.Count>0 && !string.IsNullOrEmpty(this._LinkageComponent.TgtSrcKeyField))
                {
                    for(int i=0;i<this.cbo_TgtSrcKey.Items.Count;i++)
                    {
                        if(this.cbo_TgtSrcKey.Items[i].ToString()==this._LinkageComponent.TgtSrcKeyField)
                        {
                            this.cbo_TgtSrcKey.SelectedIndex = i;
                            break;
                        }
                    }
                }
                if (this.cbo_TgtRefKey.Items.Count > 0 && !string.IsNullOrEmpty(this._LinkageComponent.TgtRefKeyField))
                {
                    for (int i = 0; i < this.cbo_TgtRefKey.Items.Count; i++)
                    {
                        if (this.cbo_TgtRefKey.Items[i].ToString() == this._LinkageComponent.TgtRefKeyField)
                        {
                            this.cbo_TgtRefKey.SelectedIndex = i;
                            break;
                        }
                    }
                }
                if (this.cbo_TgtLinkScore.Items.Count > 0 && !string.IsNullOrEmpty(this._LinkageComponent.TgtLinkScoreField))
                {
                    for (int i = 0; i < this.cbo_TgtLinkScore.Items.Count; i++)
                    {
                        if (this.cbo_TgtLinkScore.Items[i].ToString() == this._LinkageComponent.TgtLinkScoreField)
                        {
                            this.cbo_TgtLinkScore.SelectedIndex = i;
                            break;
                        }
                    }
                }
            }
        }

        public void SaveSettings()
        {
            this._LinkageComponent.ParentDbProvider = (DataProviderType) this.cbo_SrcDbProvider.SelectedIndex;
            this._LinkageComponent.ParentConnStr = this.txt_SrcConnStr.Text;
            this._LinkageComponent.ParentSql = this.rt_SrcSql.Text;
            this._LinkageComponent.ParentKeyFieldName = this.cbo_SrcKey.Text;

            this._LinkageComponent.ChildDbProvider = (DataProviderType)this.cbo_RefDbProvider.SelectedIndex;
            this._LinkageComponent.ChildConnStr = this.txt_RefConnStr.Text;
            this._LinkageComponent.ChildSql = this.rt_RefSql.Text;
            this._LinkageComponent.ChildPKFieldName = this.cbo_RefPK.Text;
            this._LinkageComponent.ChildFKFieldName = this.cbo_RefFK.Text;

            this._LinkageComponent.ReferenceType = (EntityReferenceType)this.cbo_RefDbProvider.SelectedIndex;
            this._LinkageComponent.HopFactor = (double)this.num_HopFactor.Value;
            this._LinkageComponent.LinkageSimilarityThreshold = (double)this.num_SimilarityThreshold.Value;

            this._LinkageComponent.TgtDbProvider = (DataProviderType)this.cbo_TgtDbProvider.SelectedIndex;
            this._LinkageComponent.TgtConnStr = this.txt_TgtConnStr.Text;
            this._LinkageComponent.TgtTable = this.cbo_TgtTable.Text;
            this._LinkageComponent.TgtSrcKeyField = this.cbo_TgtSrcKey.Text;
            this._LinkageComponent.TgtRefKeyField = this.cbo_TgtRefKey.Text;
            this._LinkageComponent.TgtLinkScoreField = this.cbo_TgtLinkScore.Text;
        }

        public TestResult Test()
        {
            throw new NotImplementedException();
        }

        #endregion

        private void btn_OK_Click(object sender, EventArgs e)
        {
            this.SaveSettings();

            if (this.UpdateComponentSettingEvent != null)
                this.UpdateComponentSettingEvent(this._ActivityNode, this._LinkageComponent);

            this.Close();
        }

        private void btn_Cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btn_RefreshRef_Click(object sender, EventArgs e)
        {
            if(!string.IsNullOrEmpty(this.txt_RefConnStr.Text ) && 
                !string.IsNullOrEmpty(this.rt_RefSql.Text))
            {
                DataProviderType dbProvider = (DataProviderType)this.cbo_RefDbProvider.SelectedIndex;
                this.cbo_RefPK.Items.Clear();
                this.cbo_RefFK.Items.Clear();
                string sql = this.rt_RefSql.Text;
                if(sql.IndexOf("{0}")>=0)
                {
                    sql = sql.Replace("{0}", "1");
                }
                TableColumn[] refCols = 
                    DbUtil.GetTableColumns(
                        dbProvider, this.txt_RefConnStr.Text, sql);
                if(refCols !=null && refCols.Length>0)
                {
                    foreach(TableColumn col in refCols)
                    {
                        this.cbo_RefPK.Items.Add(col.ColumnName);
                        this.cbo_RefFK.Items.Add(col.ColumnName);
                    }
                }
            }
        }

        private void btn_RefreshSrc_Click(object sender, EventArgs e)
        {
            if(!string.IsNullOrEmpty( this.txt_SrcConnStr.Text) && 
                !string.IsNullOrEmpty(this.rt_SrcSql.Text))
            {
                DataProviderType dbProvider = (DataProviderType)this.cbo_SrcDbProvider.SelectedIndex;
                this.cbo_SrcKey.Items.Clear();
                TableColumn[] cols = DbUtil.GetTableColumns(dbProvider, this.txt_SrcConnStr.Text, this.rt_SrcSql.Text);
                if(cols !=null && cols.Length>0)
                {
                    foreach(TableColumn col in cols)
                    {
                        this.cbo_SrcKey.Items.Add(col.ColumnName);
                    }
                }
            }
        }

        private void btn_RefreshTgtTable_Click(object sender, EventArgs e)
        {
            if(!string.IsNullOrEmpty(this.txt_TgtConnStr.Text))
            {
                DataProviderType dbProvider = (DataProviderType)this.cbo_TgtDbProvider.SelectedIndex;
                this.cbo_TgtTable.Items.Clear();
                string[] tblNames = DbUtil.GetTableNames(dbProvider, string.Empty, this.txt_TgtConnStr.Text);
                if(tblNames !=null)
                {
                    foreach(string tbl in tblNames)
                    {
                        this.cbo_TgtTable.Items.Add(tbl);
                    }

                    if(!string.IsNullOrEmpty(this._LinkageComponent.TgtTable))
                    {
                        for(int i=0;i<this.cbo_TgtTable.Items.Count;i++)
                        {
                            if(this.cbo_TgtTable.Items[i].ToString()==this._LinkageComponent.TgtTable)
                            {
                                this.cbo_TgtTable.SelectedIndex = i;
                                break;
                            }
                        }

                        if (this.cbo_TgtSrcKey.Items.Count > 0 && !string.IsNullOrEmpty(this._LinkageComponent.TgtSrcKeyField))
                        {
                            for (int i = 0; i < this.cbo_TgtSrcKey.Items.Count; i++)
                            {
                                if (this.cbo_TgtSrcKey.Items[i].ToString() == this._LinkageComponent.TgtSrcKeyField)
                                {
                                    this.cbo_TgtSrcKey.SelectedIndex = i;
                                    break;
                                }
                            }
                        }
                        if (this.cbo_TgtRefKey.Items.Count > 0 && !string.IsNullOrEmpty(this._LinkageComponent.TgtRefKeyField))
                        {
                            for (int i = 0; i < this.cbo_TgtRefKey.Items.Count; i++)
                            {
                                if (this.cbo_TgtRefKey.Items[i].ToString() == this._LinkageComponent.TgtRefKeyField)
                                {
                                    this.cbo_TgtRefKey.SelectedIndex = i;
                                    break;
                                }
                            }
                        }
                        if (this.cbo_TgtLinkScore.Items.Count > 0 && !string.IsNullOrEmpty(this._LinkageComponent.TgtLinkScoreField))
                        {
                            for (int i = 0; i < this.cbo_TgtLinkScore.Items.Count; i++)
                            {
                                if (this.cbo_TgtLinkScore.Items[i].ToString() == this._LinkageComponent.TgtLinkScoreField)
                                {
                                    this.cbo_TgtLinkScore.SelectedIndex = i;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        private void cbo_TgtTable_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(this.cbo_TgtTable.SelectedIndex>=0)
            {
                DataProviderType dbProvider = (DataProviderType)this.cbo_TgtDbProvider.SelectedIndex;
                string connStr = this.txt_TgtConnStr.Text;
                string tblName = this.cbo_TgtTable.SelectedItem.ToString();

                this.cbo_TgtSrcKey.Items.Clear();
                this.cbo_TgtRefKey.Items.Clear();
                this.cbo_TgtLinkScore.Items.Clear();

                TableColumn[] cols = DbUtil.GetTableColumns(dbProvider, connStr, string.Empty, tblName);
                if(cols !=null && cols.Length>0)
                {
                    foreach(TableColumn col in cols)
                    {
                        this.cbo_TgtSrcKey.Items.Add(col.ColumnName);
                        this.cbo_TgtRefKey.Items.Add(col.ColumnName);
                        this.cbo_TgtLinkScore.Items.Add(col.ColumnName);
                    }
                }
            }
        }

        
    }
}
